#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from Config.GlobalVariables import PAGE_PROPERTY_PATH
from Config.GlobalVariables import RESULTS_SEARCHRESULTS_PATH
import os
import json


class ParsePageProperty(object):

    def __init__(self):
        self.page_property = None
        try:
            with open(PAGE_PROPERTY_PATH, "r", encoding="utf-8") as r:
                self.page_property = json.load(r)
        except Exception as e:
            raise e

    @staticmethod
    def get_key_path_by_key(dic, obj_key):
        """
        根据目标key，递归获取该key在字典中的路径，并以列表形式返回。
        :param dic: 字典
        :param obj_key: 目标key
        :return: 包含路径的列表
        """
        def rec(r_dic, key_path, key_path_list):
            for key in r_dic.keys():
                if key != obj_key and isinstance(r_dic[key], dict):
                    rec(r_dic[key], key_path + [key], key_path_list)
                elif key == obj_key:
                    key_path = key_path + [key]
                    key_path_list.append(key_path)
                    key_path = []
            return key_path_list
        return rec(dic, [], [])

    @staticmethod
    def get_value(dic, key_path):
        """
        根据key的路径，递归获取其在字典中的value。
        :param dic: 字典
        :param key_path: 以[key, subkey, sub2key] 形式显示的列表
        :return: 路径对应的value
        """
        def rec(r_dic, r_key_path, value):
            for key in r_key_path:
                if key not in r_dic.keys():
                    value = []
                elif len(r_key_path) > 1:
                    r_key_path.pop(0)
                    rec(r_dic[key], r_key_path, value)
                else:
                    value.append(r_dic[key])
            return value[0]
        return rec(dic, key_path, [])

    @staticmethod
    def set_value(dic, key_path, value):
        """
        根据key的路径，递归获取其在字典中的value，将其改变为想要设置的值。
        :param dic: 字典
        :param key_path: 以[key, subkey, sub2key] 形式显示的列表
        :param value: 需要设置的值
        :return: 新dic
        """
        def rec(r_dic, r_key_path, r_value):
            for key in r_key_path:
                if key not in r_dic.keys():
                    return r_dic
                elif len(r_key_path) > 1:
                    r_key_path.pop(0)
                    rec(r_dic[key], r_key_path, r_value)
                else:
                    r_dic[key] = r_value
            return r_dic
        return rec(dic, key_path, value)

    def get_property_path(self, obj_property):
        """
        获取页面资源在Json文件中的路径
        :param obj_property: 目标资源
        :return: 路径，key.subkey 形式的字符串
        """
        key_lists, new_path_list = [], []
        try:
            key_path_lists = ParsePageProperty.get_key_path_by_key(self.page_property, obj_property)
            for key_path_list in key_path_lists:
                new_key_path = ".".join(key_path_list)
                new_path_list.append(new_key_path)
        except Exception as e:
            raise e
        finally:
            return new_path_list

    def get_property_value(self, property_path):
        """
        获取页面资源在Json文件中的值
        :param property_path: 页面资源在Json文件中的路径，key.subkey 形式的字符串
        :return: 资源的值
        """
        property_value = None
        try:
            key_path = property_path.split(".")
            property_value = ParsePageProperty.get_value(self.page_property, key_path)
        except Exception as e:
            raise e
        finally:
            return property_value

    def set_property_value(self, property_path, value):
        """
        更改页面资源在Json文件中的值
        :param property_path: 页面资源在Json文件中的路径，key.subkey 形式的字符串
        :param value: 新value
        :return: 新PageProperty
        """
        new_page_property = None
        try:
            key_path = property_path.split(".")
            new_page_property = ParsePageProperty.set_value(self.page_property, key_path, value)
            with open(PAGE_PROPERTY_PATH, "w", encoding='utf-8') as f:
                json.dump(new_page_property, f, indent=4, ensure_ascii=False)
        except Exception as e:
            raise e
        finally:
            return new_page_property

    def parse_list(self, list_path):
        li = self.get_property_value(list_path)
        return li if isinstance(li, list) else None

    def parse_string(self, string_path):
        string = self.get_property_value(string_path)
        return string if isinstance(string, str) else None

    def parse_locator(self, locator_path):
        locator = self.get_property_value(locator_path)
        return (locator[0], locator[1]) if isinstance(locator, list) and len(locator) == 2 else None

    @staticmethod
    def make_dict(key_list, value_list):
        str_key_list = map(str, key_list)
        dic = dict(zip(str_key_list, value_list))
        return dic

    @staticmethod
    def make_search_result_json_file(dic, filename):
        try:
            if not os.path.exists(RESULTS_SEARCHRESULTS_PATH):
                os.makedirs(RESULTS_SEARCHRESULTS_PATH)
            filepath = os.path.join(RESULTS_SEARCHRESULTS_PATH, filename)
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(dic, f, indent=4)
        except Exception as e:
            raise e

    @staticmethod
    def parse_search_result(filepath):
        search_result = None
        try:
            with open(filepath, "r", encoding="utf-8") as r:
                search_result = json.load(r)
        except Exception as e:
            raise e
        finally:
            return search_result


if __name__ == "__main__":
    parser = ParsePageProperty()
    print(parser.get_property_path("cookies"))
    print(parser.get_property_path([]))
    print(parser.get_property_path(123))
    print("=====================================")
    print(parser.get_property_value("ACToys.TransformerTradePage.cookies"))
    print(parser.get_property_value("[]"))
    print(parser.get_property_value("asd"))
    print("=====================================")
    print(parser.set_property_value("ACToys.TransformerTradePage.cookies", ["123", {"h": 123}]))
    print(parser.set_property_value("ACToys.TransformerTradePage.123", ["123", {"h": 123}]))
    print(parser.set_property_value("asd", ["123", {"h": 123}]))
